#pragma once

#include <osg\ref_ptr>
#include <osg/Vec3>
#include <osg/Vec4>
#include <osg/MatrixTransform>
#include "transformable.h"
#include <QString>
#include "corebase_global.h"

#define BIT(a) (long(1L<<long(a)))

namespace osg
{
	class Geode;
	class Switch;
}

namespace CoreBase
{
	class COREBASE_EXPORT PointAxis : public Transformable
	{
	public:
		enum  AXIS
		{
			X              = 0L,
			Y,
			Z,
			NUMAXES
		};
		enum  AXISCOLOR
		{
			BLACK          = 0L,
			WHITE,
			RED,
			YELLOW,
			GREEN,
			CYAN,
			BLUE,
			MAGENTA,
			CUSTOM_X,
			CUSTOM_Y,
			CUSTOM_Z,

			NUMAXISCOLORS
		};
		enum  FLAG
		{
			AXES           = BIT(0L),
			LABELS         = BIT(1L),
			LABEL_X        = BIT(2L),
			LABEL_Y        = BIT(3L),
			LABEL_Z        = BIT(4L),
			XYZ_LABELS     = BIT(5L),
			HPR_LABELS     = BIT(6L),
			CUSTOM_LABELS  = BIT(7L)
		};
	private:
		enum  BASE_COLOR
		{
			BASECOLORS     = MAGENTA   + 1L
		};
		static   const float       DEF_AXIS_SIZE;          ///< default size of axis lines
		static   const float       DEF_CHAR_SIZE;          ///< multiplier for character size
		static   const AXISCOLOR   DEF_COLOR[NUMAXES];     ///< default axis colors XYZ=RGB
		static   const char*       DEF_LABEL_XYZ[NUMAXES]; ///< default labels "X" "Y" "Z"
		static   const char*       DEF_LABEL_HPR[NUMAXES]; ///< alternate labels "H" "P" "R"
		static   const osg::Vec4   COLOR[BASECOLORS];      ///< preset color values
	public:
		PointAxis();
	protected:
		virtual              ~PointAxis();
	public:
		virtual  void        enable(int f);
		virtual  void        disable(int f);
		virtual  const char* getLabel(AXIS a)                     const;
		virtual  void        setLabel(AXIS a, const char* l);
		virtual  float       getLength(AXIS a)                    const;
		virtual  void        setLength(AXIS a, float l);
		virtual  AXISCOLOR   getColor(AXIS a)                     const;
		virtual  void        setColor(AXIS a, AXISCOLOR c);
		virtual  void        getColor(AXIS a, osg::Vec4& c)       const;
		virtual  void        setColor(AXIS a, const osg::Vec4 c);
		virtual  AXISCOLOR   getLabelColor(AXIS a)                const;
		virtual  void        setLabelColor(AXIS a, AXISCOLOR c);
		virtual  void        getLabelColor(AXIS a, osg::Vec4& c)  const;
		virtual  void        setLabelColor(AXIS a, const osg::Vec4 c);
		virtual void         setCharacterScale(float size);
		virtual float        getCharacterScale() const;
	private:
		inline   void        ctor();
		inline   void        axesSetup();
		inline   void        labelSetup(osg::Geode* g, const char* l, osg::Vec3 p, osg::Vec4 c, float s = 1.0f);
	private:
		QString						_label[NUMAXES];     ///< lable for each axis
		QString						_cLabel[NUMAXES];    ///< user labels for each axis
		AXISCOLOR                     _colorID[NUMAXES];   ///< color id for each axis
		AXISCOLOR                     _lColorID[NUMAXES];  ///< color id for each axis label
		osg::Vec4                     _color[NUMAXES];     ///< color for each axis
		osg::Vec4                     _lColor[NUMAXES];    ///< color for each label
		osg::Vec3                     _point[NUMAXES+1L];  ///< data points to construct geometry
		osg::ref_ptr<osg::Switch>     _mainSwitch;         ///< toggle for axis and all lables
		osg::ref_ptr<osg::Switch>     _labelSwitch;        ///< toggle for individual labels
		float                         _characterScale;     ///< scale the size of label characters
	};
}